#!/bin/bash

# Containerlab快速开发脚本

set -e

cd "$(dirname "$0")/.."

# 配置
IMAGE_NAME="rbgp-osken"
BASE_TAG="base"
DEV_TAG="dev"
FAST_TAG="fast"

show_help() {
    echo "Containerlab快速开发工具"
    echo ""
    echo "使用方法:"
    echo "  $0 init          # 初次构建基础镜像（只需要做一次）" 
    echo "  $0 build         # 快速构建开发镜像（修改源码后使用）"
    echo "  $0 build-fast    # 超快速构建（使用多阶段缓存）"
    echo "  $0 restart-clab  # 重启containerlab拓扑"
    echo "  $0 stop-clab     # 关闭指定containerlab拓扑"
    echo "  $0 clean         # 清理所有镜像"
    echo "  $0 status        # 查看镜像状态"
    echo "  $0 diagnose      # 诊断containerlab状态"
    echo ""
    echo "推荐工作流："
    echo "  1. 首次使用: $0 init"
    echo "  2. 修改代码后: $0 build && $0 restart-clab"
    echo "  3. 或者使用: $0 build-fast && $0 restart-clab"
    echo "  4. 关闭拓扑: $0 stop-clab"
    echo "  5. 诊断问题: $0 diagnose"
    echo ""
}

init_build() {
    echo "🚀 构建基础镜像（包含所有依赖）..."
    docker build -f docker/Dockerfile.fast --target base -t ${IMAGE_NAME}:${BASE_TAG} .
    
    echo "🚀 构建依赖镜像..."
    docker build -f docker/Dockerfile.fast --target deps -t ${IMAGE_NAME}:deps .
    
    echo "✅ 基础镜像构建完成！"
    echo "现在可以使用 '$0 build' 进行快速构建"
}

fast_build() {
    echo "⚡ 快速构建开发镜像..."
    
    # 使用时间戳标记，避免缓存问题
    BUILD_TIME=$(date +%s)
    
    docker build \
        -f docker/Dockerfile.fast \
        --build-arg BUILD_TIME=${BUILD_TIME} \
        -t ${IMAGE_NAME}:${DEV_TAG} \
        -t ${IMAGE_NAME}:latest .
    
    echo "✅ 快速构建完成！镜像: ${IMAGE_NAME}:${DEV_TAG}"
    echo "可以使用 '$0 restart-clab' 重启拓扑"
}

build_clab() {
    echo "⚡ 构建containerlab专用镜像..."
    
    docker build \
        -f docker/Dockerfile.clab \
        -t ${IMAGE_NAME}:${DEV_TAG} \
        -t ${IMAGE_NAME}:latest .
    
    echo "✅ 构建完成！镜像: ${IMAGE_NAME}:${DEV_TAG}"
}

restart_containerlab() {
    echo "🔄 重启containerlab拓扑..."
    
    # 检查是否在topo目录
    TOPO_DIRS=$(find topo -name "*.clab.yaml" 2>/dev/null | head -1)
    
    if [ -z "$TOPO_DIRS" ]; then
        echo "❌ 未找到containerlab配置文件"
        echo "请在包含.clab.yaml文件的目录下运行此命令"
        return 1
    fi
    
    echo "请选择要重启的拓扑:"
    find topo -name "*.clab.yaml" | nl
    read -p "请输入编号: " choice
    
    SELECTED_TOPO=$(find topo -name "*.clab.yaml" | sed -n "${choice}p")
    
    if [ -z "$SELECTED_TOPO" ]; then
        echo "❌ 无效选择"
        return 1
    fi
    
    TOPO_DIR=$(dirname "$SELECTED_TOPO")
    TOPO_FILE=$(basename "$SELECTED_TOPO")
    
    echo "🔄 重启拓扑: $SELECTED_TOPO"
    
    cd "$TOPO_DIR"
    
    # 停止现有拓扑
    sudo containerlab destroy -t "$TOPO_FILE" --cleanup || true
    
    # 等待清理完成
    sleep 2
    
    # 启动新拓扑
    sudo containerlab deploy -t "$TOPO_FILE"
    
    echo "✅ 拓扑重启完成！"
}

stop_containerlab() {
    echo "🛑 关闭指定containerlab拓扑..."
    
    # 检查是否有topo目录和配置文件
    TOPO_DIRS=$(find topo -name "*.clab.yaml" 2>/dev/null | head -1)
    
    if [ -z "$TOPO_DIRS" ]; then
        echo "❌ 未找到containerlab配置文件"
        echo "请在包含.clab.yaml文件的目录下运行此命令"
        return 1
    fi
    
    echo "请选择要关闭的拓扑:"
    find topo -name "*.clab.yaml" | nl
    read -p "请输入编号（按回车取消）: " choice
    
    if [ -z "$choice" ]; then
        echo "❌ 操作已取消"
        return 0
    fi
    
    SELECTED_TOPO=$(find topo -name "*.clab.yaml" | sed -n "${choice}p")
    
    if [ -z "$SELECTED_TOPO" ]; then
        echo "❌ 无效选择"
        return 1
    fi
    
    TOPO_DIR=$(dirname "$SELECTED_TOPO")
    TOPO_FILE=$(basename "$SELECTED_TOPO")
    
    echo "🛑 正在关闭拓扑: $SELECTED_TOPO"
    
    cd "$TOPO_DIR"
    
    # 关闭拓扑
    sudo containerlab destroy -t "$TOPO_FILE" --cleanup
    
    echo "✅ 拓扑 $TOPO_FILE 已关闭！"
}

stop_all_containerlab() {
    echo "🛑 关闭所有containerlab拓扑..."
    
    # 检查是否有topo目录和配置文件
    TOPO_FILES=$(find topo -name "*.clab.yaml" 2>/dev/null)
    
    if [ -z "$TOPO_FILES" ]; then
        echo "ℹ️  未找到containerlab配置文件"
        return 0
    fi
    
    echo "发现以下拓扑配置文件:"
    echo "$TOPO_FILES" | nl
    echo ""
    
    read -p "确认要关闭所有拓扑吗？(y/N): " confirm
    
    if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
        echo "❌ 操作已取消"
        return 0
    fi
    
    echo "🛑 正在关闭所有拓扑..."
    
    # 逐个关闭所有拓扑
    echo "$TOPO_FILES" | while read -r topo_path; do
        if [ -n "$topo_path" ]; then
            TOPO_DIR=$(dirname "$topo_path")
            TOPO_FILE=$(basename "$topo_path")
            
            echo "🛑 关闭拓扑: $topo_path"
            
            (cd "$TOPO_DIR" && sudo containerlab destroy -t "$TOPO_FILE" --cleanup) || \
            echo "⚠️  关闭 $topo_path 时出现问题"
            
            echo "✅ 已处理: $TOPO_FILE"
        fi
    done
    
    echo "✅ 所有拓扑处理完成！"
}

diagnose_containerlab() {
    echo "🔍 Containerlab 诊断工具"
    echo "=========================="
    
    # 1. 检查 containerlab 安装
    echo ""
    echo "1️⃣ 检查 containerlab 安装:"
    if command -v containerlab >/dev/null 2>&1; then
        echo "✅ containerlab 命令可用"
        echo "版本信息:"
        containerlab version 2>/dev/null || echo "❌ 无法获取版本信息"
    else
        echo "❌ containerlab 命令未找到"
        echo "请先安装 containerlab: https://containerlab.dev/install/"
        return 1
    fi
    
    # 2. 检查权限
    echo ""
    echo "2️⃣ 检查权限:"
    if sudo -n true 2>/dev/null; then
        echo "✅ sudo 权限可用"
    else
        echo "⚠️  sudo 权限可能有问题"
    fi
    
    # 3. 检查 Docker
    echo ""
    echo "3️⃣ 检查 Docker 状态:"
    if command -v docker >/dev/null 2>&1; then
        echo "✅ Docker 命令可用"
        echo "运行中的容器总数: $(docker ps | tail -n +2 | wc -l)"
        echo "所有容器总数: $(docker ps -a | tail -n +2 | wc -l)"
    else
        echo "❌ Docker 命令未找到"
    fi
    
    # 4. 检查 containerlab 相关容器
    echo ""
    echo "4️⃣ 检查 containerlab 相关容器:"
    
    # 通过名称模式检查
    CLAB_NAMED=$(docker ps --format "{{.Names}}" | grep '^clab-' || true)
    if [ -n "$CLAB_NAMED" ]; then
        echo "✅ 找到名称匹配 'clab-*' 的容器:"
        echo "$CLAB_NAMED"
        
        # 尝试提取拓扑名称
        echo ""
        echo "📋 从容器名称推断的拓扑名称:"
        EXTRACTED_TOPOS=$(echo "$CLAB_NAMED" | sed 's/^clab-//' | sed 's/-[^-]*$//' | sort -u)
        echo "$EXTRACTED_TOPOS"
    else
        echo "❌ 未找到名称匹配 'clab-*' 的容器"
    fi

    # 6. 检查配置文件
    echo ""
    echo "6️⃣ 检查配置文件:"
    TOPO_FILES=$(find topo -name "*.clab.yaml" 2>/dev/null || true)
    if [ -n "$TOPO_FILES" ]; then
        echo "✅ 找到以下拓扑配置文件:"
        echo "$TOPO_FILES"
    else
        echo "❌ 未找到拓扑配置文件"
    fi
    
    # 7. 总结和建议
    echo ""
    echo "7️⃣ 诊断总结:"
    if [ -z "$CLAB_LABELED" ] && [ -z "$CLAB_NAMED" ]; then
        echo "📋 当前没有运行中的 containerlab 拓扑"
        echo "💡 建议:"
        echo "   - 使用 '$0 restart-clab' 启动拓扑"
        echo "   - 或手动执行: cd topo/xxx && sudo containerlab deploy -t xxx.clab.yaml"
    else
        echo "📋 发现运行中的拓扑，但 stop-clab 可能无法正确识别"
        echo "💡 建议:"
        echo "   - 手动关闭: sudo containerlab destroy -t <拓扑名>"
        echo "   - 或使用: docker stop <容器名>"
    fi
}

show_status() {
    echo "📊 镜像状态:"
    docker images | grep ${IMAGE_NAME} || echo "未找到相关镜像"
    
    echo ""
    echo "📊 Containerlab状态:"
    echo "🔍 执行 containerlab inspect --all:"
    RUNNING_LABS=$(sudo containerlab inspect --all 2>&1)
    if [ -n "$RUNNING_LABS" ]; then
        echo "$RUNNING_LABS"
    else
        echo "containerlab inspect --all 无输出"
    fi
    
    echo ""
    echo "🔍 执行 containerlab list:"
    CLAB_LIST=$(sudo containerlab list 2>&1)
    if [ -n "$CLAB_LIST" ]; then
        echo "$CLAB_LIST"
    else
        echo "containerlab list 无输出"
    fi
    
    echo ""
    echo "📊 相关容器状态:"
    CLAB_CONTAINERS=$(docker ps -a --filter "label=clab-topo" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}\t{{.Labels}}")
    if [ -n "$CLAB_CONTAINERS" ] && [ "$CLAB_CONTAINERS" != "NAMES	STATUS	PORTS	LABELS" ]; then
        echo "$CLAB_CONTAINERS"
    else
        echo "未找到containerlab相关容器"
    fi
}

clean_images() {
    echo "🧹 清理镜像..."
    docker rmi ${IMAGE_NAME}:${BASE_TAG} 2>/dev/null || true
    docker rmi ${IMAGE_NAME}:deps 2>/dev/null || true  
    docker rmi ${IMAGE_NAME}:${DEV_TAG} 2>/dev/null || true
    docker rmi ${IMAGE_NAME}:latest 2>/dev/null || true
    docker system prune -f
    echo "✅ 清理完成"
}

case "$1" in
    "init")
        init_build
        ;;
    "build")
        build_clab
        ;;
    "build-fast")
        fast_build
        ;;
    "restart-clab")
        restart_containerlab
        ;;
    "stop-clab")
        stop_containerlab
        ;;
    "stop-all")
        stop_all_containerlab
        ;;
    "status")
        show_status
        ;;
    "diagnose")
        diagnose_containerlab
        ;;
    "clean")
        clean_images
        ;;
    "help"|"-h"|"--help"|"")
        show_help
        ;;
    *)
        echo "❌ 未知命令: $1"
        show_help
        exit 1
        ;;
esac
